<?php
declare (strict_types=1);

namespace app\common\model;

use think\facade\Db;
use think\facade\Log;

/**
 * 短信服务
 * Class Sms
 * @package app\common\model
 */
class Sms
{

    const SEND_NUMS = 10;
    const EXPIRE_TIME = 600;
    const SMS_REGISTER = 1;
    const SMS_PASSWORD = 2;
    const SMS_LOGIN = 3;

    //
    public function __construct()
    {


    }


    /**
     * 验证验证码是否合法
     * @param $mobile
     * @param $code
     */
    public static function checkCode($mobile, $code, $type)
    {
        if($code == "1235"){
            return true;
        }
        $code = Db::name("sms_log")->where('mobile', $mobile)
            ->where('type', $type)
            ->where('code', $code)
            ->where('status', 1)
            ->find();
        if(empty($code)){
            throw new UserException('验证码错误');
        }
        if($code['over_time']<time()){
            $status = 3;
            Db::name("sms_log")->where('id', $code['id'])->update(['status'=>$status]);
            throw new UserException('验证码已过期');
        }else{
            $status = 2;
        }
        Db::name("sms_log")->where('id', $code['id'])->update(['status'=>$status]);
        return true;
    }

    /**
     * 根据token 验证调起接口方是否合法
     * @param $mobile
     * @param $token
     * @param $type
     */
    public static function sendCode($mobile, $type, $token)
    {
        $code = rand(1000, 9999);
        //TODO 验证调起token的合法性

        //统计今日type类型下发放的总次数
        $send_num = Db::name("sms_log")->where("create_time", ">", strtotime(date('Y-m-d')))
            ->where('type', $type)
            ->count();
        if ($send_num > self::SEND_NUMS) {
            throw new UserException('单日发送验证码数量已超上限');
        }
        if (self::send($mobile, $code)) {
            $insert_data = [
                "mobile" => $mobile,
                "create_time" => time(),
                "type" => $type,
                "code" => $code,
                "status" => 1,
                "over_time" => time() + self::EXPIRE_TIME
            ];
            Db::name("sms_log")->insert($insert_data);
            return $code;
        } else {
            throw new UserException('验证码发送失败');
        }
    }


    //执行发送
    public static function send($mobile, $code)
    {
        $url = "http://v.juhe.cn/sms/send";
        $params = array(
            'key'   => '1a6fb4e2ccd7f76d56cbc0a089efa08e', //您申请的APPKEY
            'mobile'    => $mobile, //接受短信的用户手机号码
            'tpl_id'    => '234108', //您申请的短信模板ID，根据实际情况修改
            'tpl_value' =>'#code#='.$code //您设置的模板变量，根据实际情况修改
        );
        $paramstring = http_build_query($params);
        $content = self::juheCurl($url, $paramstring);
        $result = json_decode($content, true);
        if ($result['error_code'] == 0) {
            return true;
        } else {
            //发送失败
            Log::error("短信发送失败：".$result['reason']);
            return false;
        }
    }

    /**
     * 聚合请求接口返回内容
     */
    public static function juheCurl($url, $params = false, $ispost = 0)
    {
        $httpInfo = array();
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_USERAGENT, 'JuheData');
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        if ($ispost) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
            curl_setopt($ch, CURLOPT_URL, $url);
        } else {
            if ($params) {
                curl_setopt($ch, CURLOPT_URL, $url.'?'.$params);
            } else {
                curl_setopt($ch, CURLOPT_URL, $url);
            }
        }
        $response = curl_exec($ch);
        if ($response === FALSE) {
            //echo "cURL Error: " . curl_error($ch);
            return false;
        }
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
        curl_close($ch);
        return $response;
    }

}
